#!/bin/bash

# cjgit - PR Command
# Prepare and create PR for changes across projects

# Source common functions
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/cjgit-common.sh"

# Function to push specific projects (copied from push command)
push_specific_projects() {
    local projects_to_push=("$@")
    local push_failed=false
    
    print_info "Pushing changes to remote for ${#projects_to_push[@]} projects..."
    echo
    
    for project in "${projects_to_push[@]}"; do
        print_info "Pushing project: $project"
        
        # Check if project directory exists
        if [[ ! -d "$project" ]]; then
            print_error "Project directory '$project' not found!"
            push_failed=true
            continue
        fi
        
        # Check if it's a git repository
        if [[ ! -d "$project/.git" ]]; then
            print_error "'$project' is not a git repository!"
            push_failed=true
            continue
        fi
        
        # Check for local changes and warn
        if has_local_changes "$project"; then
            print_warning "Uncommitted changes detected in '$project'! Consider committing before pushing."
        fi
        
        # Get current branch
        current_branch=$(get_current_branch "$project")
        if [[ -z "$current_branch" ]]; then
            print_error "Not on any branch in '$project', skipping..."
            push_failed=true
            continue
        fi
        
        # Determine which remote to push to
        push_remote=$(get_push_remote "$project")
        if [[ -z "$push_remote" ]]; then
            print_error "No push remote found for '$project'. Neither myfork nor default remote is configured."
            push_failed=true
            continue
        fi
        
        print_info "Pushing branch '$current_branch' to remote '$push_remote'"
        
        # Push to the remote
        if git -C "$project" push "$push_remote" "$current_branch"; then
            print_success "Successfully pushed '$current_branch' to '$push_remote' in '$project'"
        else
            print_error "Failed to push '$current_branch' to '$push_remote' in '$project'"
            push_failed=true
        fi
        
        echo
    done
    
    if [[ "$push_failed" == true ]]; then
        print_error "Push operation failed for one or more projects"
        return 1
    else
        print_success "Push operation completed successfully"
        return 0
    fi
}

# PR command implementation
pr_command() {
    local pr_title="$1"
    
    if [[ -z "$pr_title" ]]; then
        print_error "PR title is required"
        echo
        help_command
        exit 1
    fi
    
    print_info "Starting PR preparation: $pr_title"
    print_info "Stage 1: Checking branch consistency across all projects..."
    echo
    
    # Stage 1: Check branch consistency
    local feature_branch=""
    local branch_mismatch=false
    
    for project in "${PROJECTS[@]}"; do
        print_info "Checking project: $project"
        
        # Check if project directory exists
        if [[ ! -d "$project" ]]; then
            print_error "Project directory '$project' not found!"
            exit 1
        fi
        
        # Check if it's a git repository
        if [[ ! -d "$project/.git" ]]; then
            print_error "'$project' is not a git repository!"
            exit 1
        fi
        
        # Get current branch
        current_branch=$(get_current_branch "$project")
        if [[ -z "$current_branch" ]]; then
            print_error "Not on any branch in '$project'!"
            exit 1
        fi
        
        # Check if this is the first branch we've seen
        if [[ -z "$feature_branch" ]]; then
            feature_branch="$current_branch"
            print_info "Found feature branch: $feature_branch"
        elif [[ "$current_branch" != "$feature_branch" ]]; then
            print_error "Branch mismatch in '$project': expected '$feature_branch', found '$current_branch'"
            branch_mismatch=true
        else
            print_success "Branch matches: $current_branch"
        fi
    done
    
    if [[ "$branch_mismatch" == true ]]; then
        print_error "Not all projects are on the same branch. Please ensure consistent branching."
        exit 1
    fi
    
    print_success "Stage 1 completed: All projects are on branch '$feature_branch'"
    echo
    print_info "Stage 2: Checking commits and validating commit messages..."
    echo
    
    # Stage 2: Check commits and validate messages
    local repo_names=()
    local validation_failed=false
    
    for project in "${PROJECTS[@]}"; do
        print_info "Checking project: $project"
        
        # Find the upstream remote
        upstream_remote=$(find_cangjie_remote "$project")
        if [[ -z "$upstream_remote" ]]; then
            print_error "No Cangjie remote found in '$project'!"
            exit 1
        fi
        
        # Get commits ahead of upstream/dev
        commits_ahead=$(get_commits_ahead_of_upstream_dev "$project" "$upstream_remote")
        
        if [[ -z "$commits_ahead" ]]; then
            print_info "No commits ahead of upstream/dev in '$project', skipping..."
            continue
        fi
        
        print_info "Found commits ahead of upstream/dev in '$project':"
        echo "$commits_ahead"
        
        # Validate each commit message
        while IFS= read -r commit; do
            # Extract commit hash and summary
            local commit_hash summary
            commit_hash=$(echo "$commit" | cut -d' ' -f1)
            summary=$(echo "$commit" | cut -d' ' -f2-)
            
            # Get the full commit message including body
            local full_message
            full_message=$(get_full_commit_message "$project" "$commit_hash")
            
            # Only show commit being checked
            print_info "Checking commit: ${commit_hash:0:8} - $summary"
            
            if ! validate_commit_message "$full_message"; then
                validation_failed=true
            fi
        done <<< "$commits_ahead"
        
        if [[ "$validation_failed" == false ]]; then
            repo_names+=("$project")
            print_success "All commits validated successfully in '$project'"
        fi
        
        echo
    done
    
    if [[ "$validation_failed" == true ]]; then
        print_error "Commit validation failed in one or more projects. Please fix commit messages."
        exit 1
    fi
    
    if [[ ${#repo_names[@]} -eq 0 ]]; then
        print_warning "No projects have commits ahead of upstream/dev. Nothing to create PR for."
        exit 0
    fi
    
    print_success "Stage 2 completed: Commit validation passed for ${#repo_names[@]} projects"
    echo
    print_info "Stage 3: Pushing changes to remote..."
    echo
    
    # Stage 3: Push changes to remote
    if ! push_specific_projects "${repo_names[@]}"; then
        print_error "Failed to push changes. Aborting PR creation."
        exit 1
    fi
    
    print_success "Stage 3 completed: All changes pushed successfully"
    echo
    print_info "Stage 4: Invoking PR creation script..."
    print_info "Repositories with changes: ${repo_names[*]}"
    
    # Stage 4: Invoke external script
    if command -v cjpr.sh >/dev/null 2>&1; then
        print_info "Executing: cjpr.sh \"$pr_title\" \"$feature_branch\" dev ${repo_names[*]}"
        if cjpr.sh "$pr_title" "$feature_branch" dev "${repo_names[@]}"; then
            print_success "PR creation completed successfully"
        else
            print_error "PR creation script failed"
            exit 1
        fi
    else
        print_error "cjpr.sh script not found in PATH"
        print_info "Would have executed: cjpr.sh \"$pr_title\" \"$feature_branch\" dev ${repo_names[*]}"
        exit 1
    fi
}

# Help function for PR command
help_command() {
    echo "Usage: cjgit pr <pr_title>"
    echo
    echo "Prepare and create PR for changes across projects"
    echo
    echo "Arguments:"
    echo "  pr_title    Title for the pull request"
    echo
    echo "Examples:"
    echo "  cjgit pr \"Fix login issue\"    # Create PR for changes across projects"
}

# Main execution
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
    help_command
    exit 0
fi

if [[ -z "$1" ]]; then
    print_error "PR title is required"
    echo
    help_command
    exit 1
fi

pr_command "$1"